From 6cf942ffa237d8b20dc72c578a8d8a74ac8c5759 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 23 Apr 2010 08:40:58 +0100 Subject: [PATCH] Add debug-key 'D' to dump EPT p2m table. Signed-off-by: Dongxiao Xu --- xen/arch/x86/hvm/vmx/vmx.c | 3 ++ xen/arch/x86/mm/hap/p2m-ept.c | 73 +++++++++++++++++++++++++++++++ xen/include/asm-x86/hvm/vmx/vmx.h | 1 + 3 files changed, 77 insertions(+) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index cc4d3b1e8d..b65695378f 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1444,7 +1444,10 @@ void start_vmx(void) } if ( cpu_has_vmx_ept ) + { vmx_function_table.hap_supported = 1; + setup_ept_dump(); + } vmx_function_table.hap_1gb_pgtb = ( vmx_ept_super_page_level_limit == 2 ) ? 1 : 0; diff --git a/xen/arch/x86/mm/hap/p2m-ept.c b/xen/arch/x86/mm/hap/p2m-ept.c index 1d4fe157c8..10d25bb9b0 100644 --- a/xen/arch/x86/mm/hap/p2m-ept.c +++ b/xen/arch/x86/mm/hap/p2m-ept.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include /* Non-ept "lock-and-check" wrapper */ static int ept_pod_check_and_populate(struct domain *d, unsigned long gfn, @@ -725,6 +727,77 @@ void ept_p2m_init(struct domain *d) d->arch.p2m->change_entry_type_global = ept_change_entry_type_global; } +static void ept_dump_p2m_table(unsigned char key) +{ + struct domain *d; + ept_entry_t *table, *ept_entry; + mfn_t mfn; + int order; + int i; + int is_pod; + int ret; + unsigned long index; + unsigned long gfn, gfn_remainder; + unsigned long record_counter = 0; + + for_each_domain(d) + { + if ( !(is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled) ) + continue; + + printk("\ndomain%d EPT p2m table: \n", d->domain_id); + + for ( gfn = 0; gfn <= d->arch.p2m->max_mapped_pfn; gfn += (1 << order) ) + { + gfn_remainder = gfn; + mfn = _mfn(INVALID_MFN); + table = + map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); + + for ( i = EPT_DEFAULT_GAW; i > 0; i-- ) + { + ret = ept_next_level(d, 1, &table, &gfn_remainder, + i * EPT_TABLE_ORDER); + if ( ret != GUEST_TABLE_NORMAL_PAGE ) + break; + } + + order = i * EPT_TABLE_ORDER; + + if ( ret == GUEST_TABLE_MAP_FAILED ) + goto out; + + index = gfn_remainder >> order; + ept_entry = table + index; + if ( ept_entry->avail1 != p2m_invalid ) + { + ( ept_entry->avail1 == p2m_populate_on_demand ) ? + ( mfn = _mfn(INVALID_MFN), is_pod = 1 ) : + ( mfn = _mfn(ept_entry->mfn), is_pod = 0 ); + + printk("gfn: %-16lx mfn: %-16lx order: %2d is_pod: %d\n", + gfn, mfn_x(mfn), order, is_pod); + + if ( !(record_counter++ % 100) ) + process_pending_softirqs(); + } +out: + unmap_domain_page(table); + } + } +} + +static struct keyhandler ept_p2m_table = { + .diagnostic = 0, + .u.fn = ept_dump_p2m_table, + .desc = "dump ept p2m table" +}; + +void setup_ept_dump(void) +{ + register_keyhandler('D', &ept_p2m_table); +} + /* * Local variables: * mode: C diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 7cc1f7ffea..60f5afb25d 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -357,6 +357,7 @@ void vmx_inject_nmi(void); void ept_p2m_init(struct domain *d); void ept_walk_table(struct domain *d, unsigned long gfn); +void setup_ept_dump(void); /* EPT violation qualifications definitions */ #define _EPT_READ_VIOLATION 0 -- 2.30.2